<template>
  <div class="component-container">
    <div class="query-box-content">
      <div class="query-element-group" ref="queryGroup" :style="{width:`${attr.leftBoxWidth}%`}">
        <div class="query-element" :style="{width:`${item.elementWidth?item.elementWidth:attr.elementWidth}`}" v-for="(item,index) in props.content" :key="index">
          <div class="query-element-label" :style="{flex: item.labelWidth}">{{ item.label }}</div>
          <div class="query-element-value" :style="{flex: item.valueWidth}">
            <el-input v-if="item.type === 'input'" v-model="propertyValue[item.elementName]" v-bind="item.elementProperty"/>
            <el-select v-if="item.type === 'select'" v-model="propertyValue[item.elementName]" v-bind="item.elementProperty">
              <el-option
                v-for="it in item.elementOptions"
                :key="it.value"
                :label="it.label"
                :value="it.value">
              </el-option>
            </el-select>
            <el-date-picker
              v-if="item.type === 'date'"
              v-model="propertyValue[item.elementName]"
              type="daterange"
              format="YYYY-MM-DD"
              range-separator="到"
              start-placeholder="开始时间"
              end-placeholder="结束时间"
              v-bind="item.elementProperty"
            />
          </div>
        </div>
      </div>
      <div :style="{width:`${attr.rightBoxWidth}%`}" class="right-query-box">
        <el-divider style="height:80%" direction="vertical" />
        <div class="right-query-btns" :style="{ flexDirection: isWrapper?'column':'row', alignItems: 'center'}">
          <div>
            <el-button type="primary" @click="submit">查 询</el-button>
          </div>
          <div v-if="attr.showReset">
            <el-button type="warning" @click="reset">重 置</el-button>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>
<script lang="tsx" setup>
import { PropType, ref,onBeforeMount, onBeforeUnmount } from 'vue';
import { ISelectProps , InputProps } from 'element-plus';

defineOptions({
  name: "QueryBox",
});

const emits = defineEmits(['query'])
const queryGroup = ref()

interface Map {
  label: string;
  value: number | string | boolean;
}
interface ContentItem {
  label: string;              // label的名称
  type: string;               // 组件类型
  labelWidth: number;         // label的宽度
  valueWidth: number;         // value的宽度
  elementName: string;        // 调用方的元素属性名称
  elementValueType: string;   // 属性返回值类型
  elementDefaultValue: any;   // 属性默认值
  elementWidth: number;       // 元素宽度
  elementOptions:Array<Map>;  // 下拉框选项
  elementProperty: InputProps | ISelectProps;  // 属性样式
}

const props = defineProps({
  attr: {
    type: Object as PropType<{
      leftBoxWidth: number;
      rightBoxWidth: number;
      elementWidth: number;
      elementHeight: string;
      showReset: boolean;
    }>,
    default: () => ({
      leftBoxWidth: 86,
      rightBoxWidth: 14,
      elementWidth: '320px',
      elementHeight: "40px",
      showReset: true
    })
  },
  content: {
    type: Array as PropType<ContentItem[]>,
    default: () => [
      {
        label: '搜索框',
        type: 'input', // 默认有 input,selectbox,date
        labelWidth: 3,
        valueWidth: 7,
        elementName: 'default',  // 调用方的元素属性名称
        elementValueType: 'string', // 默认 strng,number,array
        elementDefaultValue: '',
        elementProperty:{
          placeholder: '这个是默认值'
        }
      },
      {
        label: '我哈哈哈',
        type: 'select', // 默认有 input,selectbox,date
        labelWidth: 3,
        valueWidth: 7,
        elementName: 'haha',  // 调用方的元素属性名称
        elementValueType: 'string', // 默认 strng,number,array
        elementDefaultValue: '',
        elementOptions:[
          {
            label: '开始',
            value:1
          },
          {
            label: '结束',
            value:2
          }
        ],
        elementProperty:{}
      },
      {
        label: '日期时间',
        type: 'date', // 默认有 input,selectbox,date
        labelWidth: 3,
        valueWidth: 7,
        elementName: 'jaajajaj',  // 调用方的元素属性名称
        elementValueType: 'array', // 默认 strng,number,array
        elementDefaultValue: [],
        elementProperty:{}
      },
    ]
  }
})

// 监测flex-wrap是否换行

const isWrapper = ref(false)

const propertyValue = ref({})

onBeforeMount(()=>{
  initProperty()
  window.addEventListener('resize', checkWrap)
})

onBeforeUnmount(() => {
  window.removeEventListener('resize',checkWrap)
})

const checkWrap = () => {
  const container = queryGroup.value;
  const items = container.children;
  
  // 获取第一个和最后一个元素的 offsetTop
  const firstItemTop = items[0].offsetTop;
  const lastItemTop = items[items.length - 1].offsetTop;
  
  // 如果第一个和最后一个元素的 top 不相等，表示发生了换行
  isWrapper.value = firstItemTop !== lastItemTop;
}

const initProperty = () => {
  // 初始化属性
  for (let i = 0 ; i < props.content.length ; i++) {
    var property = props.content[i]
    if (property.elementDefaultValue && property.elementDefaultValue.length) {
      propertyValue.value[property.elementName] = property.elementDefaultValue
      continue
    }
    switch (property.elementValueType) {
      case 'string':
        propertyValue.value[property.elementName] = ''
        break
      case 'number':
        propertyValue.value[property.elementName] = 0
        break
      case 'array':
        propertyValue.value[property.elementName] = []
        break
    }
  }
}

const submit = () => {
  emits('query', propertyValue.value)
}

const reset = () => {
  for (let key in propertyValue.value) {
    switch (typeof propertyValue.value[key]) {
      case 'string':
        propertyValue.value[key] = ''
        break
      case 'number':
        propertyValue.value[key] = 0
        break
      case 'object':
        if (Array.isArray(propertyValue.value[key])) {
          propertyValue.value[key] = []
        }
        break
    }
  }
  emits('query', propertyValue.value)
}

defineExpose({
  propertyValue
})
</script>
<style lang="scss" scoped>
.component-container{
  width: 100%;
  border-radius: 5px;
  padding: 5px;
  min-width: 400px;
  display: flex;
  flex-direction: row;
  align-items: center;
}
.query-box-content{
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: row;
}
.query-element-group{
  display: flex;
  flex-wrap: wrap;
}
.query-element{
  display: flex;
  flex-direction: row;
  align-items: center;
  min-width: 200px;
  padding: 5px 10px;
}
.query-element-label{
  font-size: 14px;
  font-weight: 500;
  flex: 2;
}
.query-element-value{
  flex: 7;
}
.right-query-box{
  display: flex;
  flex-direction: row;
  align-items: center;
}
.right-query-btns{
  display: flex;
  flex-direction: column;
  gap: 5px;
  justify-content: space-evenly;
  height: 100%;
  ::v-deep(.el-button){
    display: block;
    border-radius: 2px;
  }
}
::v-deep(.el-input__wrapper){
  max-width: 214px;
  border-radius: 2px;
}
/**
::v-deep(.el-date-editor.el-input__wrapper){
  min-width: 108px;
  max-width: 108px;
}
  */
</style>